package cn.com.xiaoyaoji.controller;

import cn.com.xiaoyaoji.core.annotations.Ignore;
import cn.com.xiaoyaoji.core.common.DocType;
import cn.com.xiaoyaoji.core.common.Message;
import cn.com.xiaoyaoji.core.common.Pagination;
import cn.com.xiaoyaoji.core.common._HashMap;
import cn.com.xiaoyaoji.core.exception.ServiceException;
import cn.com.xiaoyaoji.core.plugin.PluginInfo;
import cn.com.xiaoyaoji.core.plugin.PluginManager;
import cn.com.xiaoyaoji.core.plugin.doc.DocExportPlugin;
import cn.com.xiaoyaoji.core.plugin.doc.DocImportPlugin;
import cn.com.xiaoyaoji.core.util.AssertUtils;
import cn.com.xiaoyaoji.core.util.ConfigUtils;
import cn.com.xiaoyaoji.core.util.ProjectSortUtils;
import cn.com.xiaoyaoji.core.util.StringUtils;
import cn.com.xiaoyaoji.data.bean.*;
import cn.com.xiaoyaoji.service.DocService;
import cn.com.xiaoyaoji.service.ProjectService;
import cn.com.xiaoyaoji.service.ServiceFactory;
import cn.com.xiaoyaoji.service.ServiceTool;
import cn.com.xiaoyaoji.utils.CXUInterface;
import cn.com.xiaoyaoji.utils.DSFInterface;
import cn.com.xiaoyaoji.utils.ZipUtil;
import cn.com.xiaoyaoji.view.MultiView;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 项目
 *
 * @author zhoujingjie
 * @date 2016-07-20
 */
@Controller
@RequestMapping("/project")
public class ProjectController {
    private static Logger logger = Logger.getLogger(ProjectController.class);

    private static String parentName;

    private static String serverName;

    private static String modelName;

    @GetMapping("/{id}/info")
    public ModelAndView detailInfo(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserIsOwner(project, user);
        return new ModelAndView("/project/info")
                .addObject("project", project)
                .addObject("pageName", "info")
                ;
    }

    @GetMapping("/{id}/member")
    public ModelAndView detailMember(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserIsMember(project, user);

        List<User> users = ServiceFactory.instance().getUsersByProjectId(id);
        return new ModelAndView("/project/member")
                .addObject("users", users)
                .addObject("project", project)
                .addObject("pageName", "member")
                .addObject("fileAccess", ConfigUtils.getFileAccessURL())
                ;
    }

    @GetMapping("/{id}/function")
    public ModelAndView detailFunction(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserIsOwner(project, user);

        List<User> users = ServiceFactory.instance().getUsersByProjectId(id);
        return new ModelAndView("/project/function")
                .addObject("pageName", "function")
                .addObject("users", users)
                .addObject("project", project)
                .addObject("fileAccess", ConfigUtils.getFileAccessURL())
                ;
    }

    @GetMapping("/{id}/transfer")
    public ModelAndView baseTransfer(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserIsOwner(project, user);
        List<User> users = ServiceFactory.instance().getUsersByProjectId(id);
        return new ModelAndView("/project/transfer")
                .addObject("pageName", "transfer")
                .addObject("project", project)
                .addObject("users", users)
                .addObject("fileAccess", ConfigUtils.getFileAccessURL())
                ;
    }

    @GetMapping("/{id}/quit")
    public ModelAndView baseRelease(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserIsMember(project, user);
        return new ModelAndView("/project/quit")
                .addObject("pageName", "quit")
                .addObject("project", project);
    }

    @Ignore
    @GetMapping("/{id}/export")
    public ModelAndView baseExport(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserHasAccessPermission(project, user);
        return new ModelAndView("/project/export")
                .addObject("project", project)
                .addObject("pageName", "export");
    }

    /**
     * 导出
     *
     * @param id   项目id
     * @param user 当前登录用户
     * @return pdfview
     */
    @Ignore
    @GetMapping(value = "/{id}/export/{pluginId}/do")
    @ResponseBody
    public void export(@PathVariable("id") String id, @PathVariable String pluginId, User user, HttpServletResponse response) throws IOException {

        Project project = ProjectService.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserHasAccessPermission(project, user);

        PluginInfo<DocExportPlugin> docExportPluginPluginInfo = PluginManager.getInstance().getExportPlugin(pluginId);
        AssertUtils.notNull(docExportPluginPluginInfo,"不支持该操作");
        docExportPluginPluginInfo.getPlugin().doExport(id,response);
    }

    /**
     * 导入json
     * @param user
     * @return
     */
    @PostMapping(value = "/import")
    @ResponseBody
    public Object projectImport(String pluginId, User user,
                                @RequestParam("file") MultipartFile file,
                                @RequestParam(value = "projectId",required = false) String projectId,
                                @RequestParam(value = "parentId",required = false) String parentId
                                ) throws IOException {
        PluginInfo<DocImportPlugin> docImportPluginPluginInfo = PluginManager.getInstance().getImportPlugin(pluginId);
        AssertUtils.notNull(docImportPluginPluginInfo,"不支持该操作");
        docImportPluginPluginInfo.getPlugin().doImport(file.getName(),file.getInputStream(),user.getId(),projectId,parentId);
        return true;
    }

    @PostMapping(value = "/import/xml")
    @ResponseBody
    public Object xmlImport(@RequestParam("file") MultipartFile file,User user){
        File f = MultipartFileToFile(file);
        if(!f.getName().endsWith(".zip")){
            throw new ServiceException("数据格式有误,仅支持zip文件");
        }
        //解析文件获取docs
        List<Doc> docs = analyzeFileToDoc(f,user);
        //批量入库
        int i = ServiceFactory.instance().batchInsertDoc(docs);
        return true;
    }

    @GetMapping("/{id}/import")
    public ModelAndView baseImport(@PathVariable("id") String id, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, Message.PROJECT_NOT_FOUND);
        ServiceTool.checkUserIsOwner(project, user);
        return new ModelAndView("/project/import")
                .addObject("pageName", "import")
                .addObject("project", project);
    }


    @Ignore
    @GetMapping("/list")
    public MultiView list(User user, @RequestParam(value = "status", required = false) String status) {
        List<Project> projects = new ArrayList<>();
        List<Project2> projects2 = new ArrayList<>();
        List<Project> open_projects = new ArrayList<>();
        List<Project2> open_projects2 = new ArrayList<>();
        if(org.apache.commons.lang3.StringUtils.isBlank(status)){
            status = Project.Status.VALID;
        }
        if(user != null){
            Pagination p = Pagination.build(new _HashMap<String, String>().add("status", status)
                    .add("userId", user.getId()));
            projects = ServiceFactory.instance().getProjects(p);
        }
        String site = "first";
        ProjectUserOrder projectUserOrder = new ProjectUserOrder();

        for (int i=0;i<projects.size();i++){
            projectUserOrder = ServiceFactory.instance().getProjectUserOrder(site,user.getId(),"PRIVATE");
            Project2 pj = new Project2();
            for (int j=0;j<projects.size();j++){
                if (projects.get(j).getId().equals(projectUserOrder.getProjectId())){
                    pj.setId(projects.get(j).getId());
                    pj.setName(projects.get(j).getName());
                    pj.setDescription(projects.get(j).getDescription());
                    pj.setCreateTime(projects.get(j).getCreateTime());
                    pj.setUserId(projects.get(j).getUserId());
                    pj.setStatus(projects.get(j).getStatus());
                    pj.setPermission(projects.get(j).getPermission());
                    pj.setEnvironments(projects.get(j).getEnvironments());
                    pj.setDetails(projects.get(j).getDetails());
                    pj.setLastUpdateTime(projects.get(j).getLastUpdateTime());
                    site = projectUserOrder.getProjectId();
                    pj.setHiddenFlag(projectUserOrder.getHiddenFlag());
                    projects2.add(pj);
                    break;
                }
            }
        }

        Pagination open = Pagination.build(new _HashMap<String, String>().add("permission", Project.Permission.PUBLIC));
        open_projects = ServiceFactory.instance().getOpenProjects(open);
        String site2 = "first";
        ProjectUserOrder projectUserOrder2 = new ProjectUserOrder();
        for (int i=0;i<open_projects.size();i++){
            Project2 pj = new Project2();
            projectUserOrder2 = ServiceFactory.instance().getProjectUserOrder(site2,user.getId(),"PUBLIC");
            for (int j=0;j<open_projects.size();j++){
                if (open_projects.get(j).getId().equals(projectUserOrder2.getProjectId())){
                    pj.setId(open_projects.get(j).getId());
                    pj.setName(open_projects.get(j).getName());
                    pj.setDescription(open_projects.get(j).getDescription());
                    pj.setCreateTime(open_projects.get(j).getCreateTime());
                    pj.setUserId(open_projects.get(j).getUserId());
                    pj.setStatus(open_projects.get(j).getStatus());
                    pj.setPermission(open_projects.get(j).getPermission());
                    pj.setEnvironments(open_projects.get(j).getEnvironments());
                    pj.setDetails(open_projects.get(j).getDetails());
                    pj.setLastUpdateTime(open_projects.get(j).getLastUpdateTime());
                    site2 = projectUserOrder2.getProjectId();
                    pj.setHiddenFlag(projectUserOrder2.getHiddenFlag());
                    open_projects2.add(pj);
                    break;
                }
            }
        }
        return new MultiView("/dashboard/index")
                .addObject("projects", projects2)
                .addObject("openProjects", open_projects2)
                ;
    }

    /**
     * 把原本的project添加进project_user_order表的脚本
     * @return
     */
    @Ignore
    @GetMapping("/listadd")
    public String listadd() {
        Project projects = new Project();
        ProjectUserOrder puo = new ProjectUserOrder();
        List<Project> open_projects = new ArrayList<>();
        List<User> user_projects = new ArrayList<>();
        List<ProjectUser> puser = new ArrayList<>();
        //设置一个顺序变量
        String change = "first";
        String status = Project.Status.VALID;
        //私有
        //Pagination p = Pagination.build(new _HashMap<String, String>().add("permission", Project.Permission.PRIVATE));
        puser = ServiceFactory.instance().getAllProjectUser();
        //公有
        Pagination open = Pagination.build(new _HashMap<String, String>().add("permission", Project.Permission.PUBLIC));
        open_projects = ServiceFactory.instance().getOpenProjects(open);
        //根据私有查询用户
        String bian = "";
        System.out.println(puser.size());
        for (int i=0;i<puser.size();i++){
            //System.out.println(bian);
            //获取project
            projects = ServiceFactory.instance().getProject(puser.get(i).getProjectId());
            if(projects!=null){
                if(projects.getPermission().equals("PRIVATE")) {
                    if(!puser.get(i).getUserId().equals(bian)||bian.equals("")){
                        change = "first";
                        bian = puser.get(i).getUserId();
                    }
                    puo.setId(StringUtils.id());
                    puo.setUserId(puser.get(i).getUserId());
                    puo.setProjectId(projects.getId());
                    puo.setHiddenFlag("NO");
                    puo.setPermission("PRIVATE");
                    puo.setPreProjectId(change);
                    ServiceFactory.instance().create(puo);
                    change = projects.getId();
                    bian = puser.get(i).getUserId();
                }
            }
        }
        ProjectUserOrder pp = new ProjectUserOrder();
        for (int i=0;i<open_projects.size();i++){
            String user = open_projects.get(i).getUserId();
            pp = ServiceFactory.instance().getProjectUserOrder("first",open_projects.get(i).getUserId(),"PRIVATE");
            if (pp!=null){
                pp.setPreProjectId(open_projects.get(i).getId());
                ServiceFactory.instance().update(pp);
            }
            puo.setId(StringUtils.id());
            puo.setUserId(open_projects.get(i).getUserId());
            puo.setProjectId(open_projects.get(i).getId());
            puo.setHiddenFlag("NO");
            puo.setPermission("PRIVATE");
            puo.setPreProjectId("first");
            ServiceFactory.instance().create(puo);
        }
        change = "first";
        //公有插入表中
        user_projects = ServiceFactory.instance().getAllUser();
        for (int j=0;j<user_projects.size();j++){
            change = "first";
            for(int i=0;i<open_projects.size();i++){
                puo.setId(StringUtils.id());
                puo.setPreProjectId(change);
                change = open_projects.get(i).getId();
                puo.setProjectId(open_projects.get(i).getId());
                puo.setUserId(user_projects.get(j).getId());
                puo.setPermission("PUBLIC");
                puo.setHiddenFlag("NO");
                ServiceFactory.instance().create(puo);
            }
        }
        return "搞定" ;
    }

    /**
     * 查询单个module对应的接口
     *
     * @param id
     * @return
     */
    @Ignore
    @GetMapping(value = "{id}/edit")
    public ModelAndView get(@PathVariable("id") String id, User user) {
        //获取project
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, "项目不存在或者无访问权限");
        String docId = DocService.instance().getFirstDocId(id);
        if (docId == null) {
            docId = DocService.instance().createDefaultDoc(id).getId();
        }
        //重定向到第一个
        return new ModelAndView("redirect:/doc/" + docId + "/edit");

    }

    @Ignore
    @GetMapping("{id}")
    public ModelAndView projectView(@PathVariable("id") String id) {
        //获取project
        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, "项目不存在或者无访问权限");
        String docId = DocService.instance().getFirstDocId(id);
        if (docId == null) {
            docId = DocService.instance().createDefaultDoc(id).getId();
        }
        //重定向到第一个
        return new ModelAndView("redirect:/doc/" + docId)
                ;
    }


    @GetMapping("/{id}/shares")
    @ResponseBody
    public Object shares(@PathVariable("id") String id) {
        return new _HashMap<>().add("shares", ServiceFactory.instance().getSharesByProjectId(id));
    }

    /**
     * 设置是否常用项目
     *
     * @param id
     * @return
     */
    @PostMapping("/{id}/commonly")
    @ResponseBody
    public int updateCommonlyUsed(@PathVariable("id") String id, User user,
                                  @RequestParam String isCommonlyUsed
    ) {
        AssertUtils.notNull(isCommonlyUsed, "isCommonlyUsed is null");
        int rs = ServiceFactory.instance().updateCommonlyUsedProject(id, user.getId(), isCommonlyUsed);
        AssertUtils.isTrue(rs > 0, "操作失败");
        return rs;
    }

    /**
     * 创建项目
     *
     * @param user
     * @param project
     * @return
     */
    @PostMapping
    @ResponseBody
    public Object create(User user, Project project) {
        project.setId(StringUtils.id());
        project.setCreateTime(new Date());
        project.setUserId(user.getId());
        project.setStatus(Project.Status.VALID);
        project.setEditable(ProjectUser.Editable.YES);
        project.setLastUpdateTime(new Date());
        AssertUtils.notNull(project.getPermission(), "missing permission");
        //把新建的项目的排序插入到数据库
        ProjectUserOrder old = ServiceFactory.instance().getProjectUserOrder("first",user.getId(),project.getPermission());
        ProjectUserOrder puo = ProjectSortUtils.sortProject(project,user);
        ServiceFactory.instance().create(puo);
        if(old!=null){
            old.setPreProjectId(puo.getProjectId());
            ServiceFactory.instance().update(old);
        }
        if (project.getPermission().equals("PUBLIC")){
            ProjectUserOrder old2 = ServiceFactory.instance().getProjectUserOrder("first",user.getId(),"PRIVATE");
            ProjectUserOrder puo2 = ProjectSortUtils.sortProject2(project,user);
            ServiceFactory.instance().create(puo2);
            if(old2!=null){
                old2.setPreProjectId(puo2.getProjectId());
                ServiceFactory.instance().update(old2);
            }
        }

        AssertUtils.notNull(project.getName(), "missing name");
        int rs = ProjectService.instance().createProject(project);
        Doc doc = DocService.instance().createDefaultDoc(project.getId());
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return new _HashMap<>()
                .add("projectId", project.getId())
                .add("docId", doc.getId())
                ;
    }

    /**
     *
     * @param user
     * @param old 移动的项目id
     * @param young 移动后项目前一位的id
     * @return
     */
    @PostMapping("/sortUpdate")
    @ResponseBody
    public Object sortUpdate(User user, String old,String young,String permission) {



        ProjectUserOrder puo = ServiceFactory.instance().getPUOByProjectId(old,user.getId(),permission);//旧位置
        ProjectUserOrder last =ServiceFactory.instance().getProjectUserOrder(old,user.getId(),permission);
        if(last!=null&&!last.equals("")){
            last.setPreProjectId(puo.getPreProjectId());
            ServiceFactory.instance().update(last);
        }
        ProjectUserOrder puo2 = ServiceFactory.instance().getPUOByProjectId(young,user.getId(),permission);//新位置前一位
        ProjectUserOrder last2 = new ProjectUserOrder();
        if (puo2==null) {
            last2 = ServiceFactory.instance().getProjectUserOrder("first", user.getId(),permission);//新位置后一位
        }else{
            last2 = ServiceFactory.instance().getProjectUserOrder(young, user.getId(),permission);//新位置后一位
        }
        if (puo2!=null&&last2!=null){
            puo.setPreProjectId(puo2.getProjectId());
            last2.setPreProjectId(puo.getProjectId());
            ServiceFactory.instance().update(puo);
            ServiceFactory.instance().update(last2);
        }else if(puo2==null) {
            puo.setPreProjectId("first");
            last2.setPreProjectId(puo.getProjectId());
            ServiceFactory.instance().update(puo);
            ServiceFactory.instance().update(last2);
        }else{
            puo.setPreProjectId(puo2.getProjectId());
            ServiceFactory.instance().update(puo);
        }
        return null;
    }

    /**
     * 更新
     *
     * @param id
     * @return
     */
    @PostMapping("{id}")
    @ResponseBody
    public Object update(@PathVariable("id") String id, User user, Project project) {
        ServiceTool.checkUserHasEditPermission(id, user);
        project.setId(id);
        project.setUserId(null);
        project.setLastUpdateTime(new Date());
        int rs = ServiceFactory.instance().update(project);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 项目转让
     *
     * @param id
     * @return
     */
    @PostMapping("/{id}/transfer")
    @ResponseBody
    public Object transfer(@PathVariable("id") String id, User user, @RequestParam String userId) {

        AssertUtils.isTrue(org.apache.commons.lang3.StringUtils.isNoneBlank(userId), "missing userId");
        Project before = ProjectService.instance().getProject(id);
        //获取projectUserOrder
        ProjectUserOrder puo = ServiceFactory.instance().getProjectUserOrder(before.getId(),user.getId(),before.getPermission());
        puo.setUserId(id);
        ServiceFactory.instance().update(puo);
        ServiceTool.checkUserIsOwner(before, user);
        Project temp = new Project();
        temp.setId(id);
        temp.setUserId(userId);
        int rs = ServiceFactory.instance().update(temp);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        ServiceFactory.instance().updateProjectUserEditable(id, userId, "YES");
        return rs;
    }

    /**
     * 删除项目
     *
     * @param id
     * @return
     */
    @DeleteMapping("{id}")
    @ResponseBody
    public Object delete(@PathVariable("id") String id, User user) {
        Project before = ProjectService.instance().getProject(id);
        AssertUtils.notNull(before,"无效请求");
        //修改部分
        ProjectUserOrder puo = ServiceFactory.instance().getPUOByProjectId(before.getId(),user.getId(),before.getPermission());
        String pro = puo.getProjectId();
        ProjectUserOrder last =ServiceFactory.instance().getProjectUserOrder(pro,user.getId(),before.getPermission());
        if(last!=null&&!last.equals("")){
            last.setPreProjectId(puo.getPreProjectId());
            ServiceFactory.instance().update(last);
        }
        ServiceFactory.instance().delete("project_user_order",puo.getId());
        if (before.getPermission().equals("PUBLIC")){
            ProjectUserOrder puo2 = ServiceFactory.instance().getPUOByProjectId(before.getId(),user.getId(),"PRIVATE");
            String pro2 = puo2.getProjectId();
            ProjectUserOrder last2 =ServiceFactory.instance().getProjectUserOrder(pro2,user.getId(),"PRIVATE");
            if(last2!=null&&!last2.equals("")){
                last2.setPreProjectId(puo2.getPreProjectId());
                ServiceFactory.instance().update(last2);
            }
            ServiceFactory.instance().delete("project_user_order",puo2.getId());
        }
        ServiceTool.checkUserIsOwner(before, user);
        Project temp = new Project();
        temp.setStatus(Project.Status.DELETED);
        temp.setLastUpdateTime(new Date());
        temp.setId(id);
        int rs = ServiceFactory.instance().update(temp);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 彻底删除
     *
     * @param id
     * @param user
     * @return
     */
    @DeleteMapping("/{id}/actual")
    @ResponseBody
    public Object deleteActual(@PathVariable("id") String id, User user) {
        ServiceTool.checkUserHasEditPermission(id, user);
        int rs = ServiceFactory.instance().deleteProject(id);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }


    /**
     * 邀请成员
     *
     * @param id
     * @return
     */
    @PostMapping("/{id}/invite")
    @ResponseBody
    public String invite(@PathVariable("id") String id, User user, @RequestParam String userId) {
        ProjectUser pu = new ProjectUser();
        pu.setId(StringUtils.id());
        pu.setUserId(userId);
        AssertUtils.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(pu.getUserId()), "missing userId");
        AssertUtils.isTrue(!ServiceFactory.instance().checkProjectUserExists(id, pu.getUserId()), "用户已存在该项目中");
        AssertUtils.isTrue(!pu.getUserId().equals(user.getId()), "不能邀请自己");
        pu.setCreateTime(new Date());
        pu.setStatus(ProjectUser.Status.PENDING);
        pu.setEditable(ProjectUser.Editable.NO);
        pu.setProjectId(id);
        int rs = ServiceFactory.instance().create(pu);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return pu.getId();
    }

    /**
     * 邀请成员
     *
     * @param id
     * @return
     */
    @PostMapping("/{id}/invite/email")
    @ResponseBody
    public String inviteByEmail(@PathVariable("id") String id, @RequestParam("email") String email, User user) {
        String userId = ServiceFactory.instance().getUserIdByEmail(email);
        AssertUtils.isTrue(userId != null, "该邮箱未注册");
        AssertUtils.isTrue(!userId.equals(user.getId()), "不能邀请自己");
        AssertUtils.isTrue(!ServiceFactory.instance().checkProjectUserExists(id, userId), "用户已存在该项目中");
        //hym

        ProjectUser pu = new ProjectUser();
        pu.setId(StringUtils.id());
        pu.setUserId(userId);
        pu.setProjectId(id);
        pu.setEditable(ProjectUser.Editable.YES);
        AssertUtils.isTrue(org.apache.commons.lang3.StringUtils.isNotBlank(pu.getProjectId()), "missing projectId");
        pu.setCreateTime(new Date());
        pu.setStatus(ProjectUser.Status.PENDING);
        int rs = ServiceFactory.instance().create(pu);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return pu.getId();
    }

    /**
     * 接受邀请
     *
     * @param inviteId
     * @return
     */
    @PostMapping("/{id}/pu/{inviteId}/accept")
    @ResponseBody
    public int acceptInvite(@PathVariable("inviteId") String inviteId) {
        ProjectUser pu = new ProjectUser();
        pu.setId(inviteId);
        pu.setStatus(ProjectUser.Status.ACCEPTED);
        int rs = ServiceFactory.instance().create(pu);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 拒绝邀请
     */
    @PostMapping("/{id}/pu/{inviteId}/refuse")
    @ResponseBody
    public int acceptRefuse(@PathVariable("inviteId") String inviteId) {
        ProjectUser pu = new ProjectUser();
        pu.setId(inviteId);
        pu.setStatus(ProjectUser.Status.REFUSED);
        int rs = ServiceFactory.instance().create(pu);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 移除成员
     *
     * @param userId userId
     * @param id     projectId
     * @return
     */
    @DeleteMapping("/{id}/pu/{userId}")
    @ResponseBody
    public int removeMember(@PathVariable("id") String id, @PathVariable("userId") String userId, User user) {
        Project project = ServiceFactory.instance().getProject(id);
        ServiceTool.checkUserIsOwner(project, user);
        AssertUtils.isTrue(!project.getUserId().equals(userId), "不能移除自己");
        AssertUtils.isTrue(user.getId().equals(project.getUserId()), "无操作权限");
        int rs = ServiceFactory.instance().deleteProjectUser(id, userId);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 设置是否可编辑
     *
     * @param projectId 项目id
     * @param userId
     * @param editable
     * @return
     */
    @PostMapping("/{id}/pu/{userId}/{editable}")
    @ResponseBody
    public int editProjectEditable(@PathVariable("id") String projectId, @PathVariable("userId") String userId, @PathVariable("editable") String editable,
                                   User user) {
        AssertUtils.isTrue(ProjectUser.Editable.YES.equals(editable) || ProjectUser.Editable.NO.equals(editable), "参数错误");
        Project project = ServiceFactory.instance().getProject(projectId);
        ServiceTool.checkUserIsOwner(project, user);
        AssertUtils.isTrue(!project.getUserId().equals(userId), "项目所有人不能修改自己的权限");
        int rs = ServiceFactory.instance().updateProjectUserEditable(projectId, userId, editable);
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 退出项目
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}/quit")
    @ResponseBody
    public int quit(@PathVariable("id") String id, User user) {

        Project project = ServiceFactory.instance().getProject(id);
        AssertUtils.notNull(project, "project not exists");
        AssertUtils.isTrue(!project.getUserId().equals(user.getId()), "项目所有人不能退出项目");
        int rs = ServiceFactory.instance().deleteProjectUser(id, user.getId());
        AssertUtils.isTrue(rs > 0, Message.OPER_ERR);
        return rs;
    }

    /**
     * 项目归档
     * @param id
     * @param user
     * @return
     */
    @PostMapping("/{id}/archive")
    public int archive(@PathVariable("id") String id, User user ){
        Project project = ProjectService.instance().getProject(id);
        AssertUtils.notNull(project, "项目不存在");
        AssertUtils.isTrue(project.getUserId().equals(user.getId()),"非项目所有者不能操作");
        Project temp = new Project();
        temp.setId(id);
        temp.setStatus(Project.Status.ARCHIVE);
        int rs= ServiceFactory.instance().update(temp);
        AssertUtils.isTrue(rs>0,"操作失败");
        return rs;
    }

    /**
     * @auther: hongwei
     * @param: [multiFile]
     * @date: 2019/5/20 8:53
     * @Description multiFile 转 file
     * @return: java.io.File
     */
    public static File MultipartFileToFile(MultipartFile multiFile) {

        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 用当前时间作为文件名，防止生成的临时文件重复
        try {
            File file = File.createTempFile(System.currentTimeMillis() + "", prefix);

            multiFile.transferTo(file);

            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private List<Doc> analyzeFileToDoc(File file,User user){
        List<Doc> docs = new LinkedList<>();
        //解压后的文件夹
        File unzipFile = ZipUtil.unZip(file.getAbsolutePath());
        //这一层级为project层
        File[] projects = unzipFile.listFiles();
        for (File projectFile:projects) {
            //遍历所有层级文件夹获得结果
            //清空
            Project project = new Project();
            project.setName(projectFile.getName());
            project.setPermission(Project.Permission.PUBLIC);
            _HashMap<String,String> map = (_HashMap)create(user, project);
            String projectId = map.get("projectId");
            String docId = map.get("docId");
            addXmlFilesToList(projectFile, docs,projectId,"0",true);
        }
        try {
            FileUtils.forceDelete(unzipFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return docs;
    }
    /**
     * @auther: hongwei
     * @param: [file, docs]
     * @date: 2019/5/20 10:56
     * @Description 文件夹结构不确定,这里用递归遍历
     * @return: java.util.List<cn.com.xiaoyaoji.data.bean.Doc>
     */
    private void addXmlFilesToList(File file,List<Doc> docs,String projectId,String parentId,boolean isProject){
        if (file.isDirectory()) {
            if (!isProject){
                Doc doc = new Doc();
                doc.setId(StringUtils.id());
                doc.setName(file.getName());
                doc.setCreateTime(new Date());
                doc.setSort(100);
                doc.setProjectId(projectId);
                doc.setLastUpdateTime(new Date());
                doc.setParentId(parentId);
                doc.setType(DocType.SYS_FOLDER.getTypeName());
                ServiceFactory.instance().create(doc);
                //传入下一次递归
                parentId = doc.getId();
                modelName = file.getName();
            }
            File[] files = file.listFiles();
            for(File tempFile:files){
                addXmlFilesToList(tempFile, docs,projectId,parentId,false);
            }
        }
        //如果是xml文件,进入解析
        else if (file.getName().endsWith(".xml")){
            Doc docInfo = new Doc();
            String content = null;
            try {
                Document document = new SAXReader().read((file));
                Element element = document.getRootElement();
                String interfaceName = element.attributeValue("name");
                content = new ObjectMapper().writeValueAsString(CXUInterface.builder(element));
                //构造表的实体类对象
                docInfo.setId(StringUtils.id());
                docInfo.setName(interfaceName);
                docInfo.setContent(content);
                docInfo.setType("sys.http");
                docInfo.setSort(100);//默认值
                docInfo.setProjectId(projectId);
                docInfo.setParentId(parentId);
                docInfo.setCreateTime(new Date());
                docs.add(docInfo);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (DocumentException e) {
                e.printStackTrace();
            }


        }
        //如果是txt文件,进入解析
        else if (file.getName().endsWith(".txt")){
            String FName = file.getName();
            String[] a = FName.split("_");
            String docName = a[0];
            String interfaceName = a[1];
            String[] c = interfaceName.split("[.]");
            interfaceName = c[0];

            if (!docName.equals(serverName)){

                serverName = docName;
                Doc doc = new Doc();
                doc.setId(StringUtils.id());
                doc.setName(docName);
                doc.setCreateTime(new Date());
                doc.setSort(100);
                doc.setProjectId(projectId);
                doc.setLastUpdateTime(new Date());
                doc.setParentId(parentId);
                doc.setType(DocType.SYS_FOLDER.getTypeName());
                ServiceFactory.instance().create(doc);
                //传入下一次递归
                parentName = doc.getId();

                Doc docInfo = new Doc();
                String content = null;
                try {
                content = new ObjectMapper().writeValueAsString(DSFInterface.builder(file,modelName));
                //构造表的实体类对象
                docInfo.setId(StringUtils.id());
                docInfo.setName(interfaceName);
                docInfo.setContent(content);
                docInfo.setType("sys.http");
                docInfo.setSort(100);//默认值
                docInfo.setProjectId(projectId);
                docInfo.setParentId(parentName);
                docInfo.setCreateTime(new Date());
                docs.add(docInfo);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }else{
                Doc docInfo = new Doc();
                String content = null;
                try {
                    content = new ObjectMapper().writeValueAsString(DSFInterface.builder(file,modelName));
                    //构造表的实体类对象
                    docInfo.setId(StringUtils.id());
                    docInfo.setName(interfaceName);
                    docInfo.setContent(content);
                    docInfo.setType("sys.http");
                    docInfo.setSort(100);//默认值
                    docInfo.setProjectId(projectId);
                    docInfo.setParentId(parentName);
                    docInfo.setCreateTime(new Date());
                    docs.add(docInfo);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

        }

    }

    /**
     * 记录用户隐藏操作
     * @param user
     * @param currProj
     * @return
     */
    @ResponseBody
    @PostMapping("/userProjHidden")
    private boolean userProjectHidden(User user, @RequestParam(value="currProj") String currProj){

//        System.out.println("niniiiiiii      " + user.getId() + currProj);

        ProjectUserOrder puo = ServiceFactory.instance().getPUOByProjectId(currProj, user.getId(),"PUBLIC");
        puo.setHiddenFlag("YES");
        ServiceFactory.instance().update(puo);
        return true;
    }

    /**
     * 恢复用户以前隐藏的条目
     * @return
     */
    @ResponseBody
    @PostMapping("/displayHidden")
    private boolean userDisplayHidden(User user, @RequestParam(value="hiddenList[]") String[] hiddenList){
        for(String s : hiddenList){
//            if("EMPTY".equals(s)) break;
            ProjectUserOrder puo = ServiceFactory.instance().getPUOByProjectId(s, user.getId(),"PUBLIC");
            puo.setHiddenFlag("NO");
            ServiceFactory.instance().update(puo);
        }
//        System.out.println(Arrays.toString(hiddenList));
        return true;
    }
    private void dsfInterface(){

    }
}
